package com.srx.elasticsearch.service;/*
package com.srx.elasticsearch.service;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import com.srx.openfeign.dto.BookDTO;
import com.srx.openfeign.dto.NoticeDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

*/
/**
 * 图书服务类，用于处理与用户相关的业务逻辑
 * <p>
 * 该类提供了多个方法，用于通过不同的查询条件从Elasticsearch中获取用户信息，
 * 并处理可能发生的I/O异常。
 * @author srx
 *//*

@Service
public class BookService
{

    private final ElasticsearchClient client;

	@Autowired
	public BookService(ElasticsearchClient client)
    {
        this.client = client;
    }




    */
/**
     * 获取所有图书的总数量
     *
     * @return 图书总数量
     * @throws IOException 当与数据库通信发生IO异常时抛出
     *//*

    public long getAllBookCount() throws IOException
    {
        return client.count(c -> c
                        .index("book"))
                .count();
    }


    */
/**
     * 根据分类ID获取该分类下的图书数量
     *
     * @param id 分类ID，用于筛选指定分类的图书
     * @return 返回指定分类下的图书总数
     * @throws IOException 当与搜索引擎通信出现IO异常时抛出
     *//*

    public long getCategoryBookCount(int id) throws IOException
    {
        return client.count(c -> c
                        .index("book")
                        .query(q -> q.
                                term(t -> t.
                                        field("category_id")
                                        .value(id)
                                )
                        ))
                .count();
    }


    */
/**
     * 根据分类ID获取该分类下的所有图书ID
     *
     * @param categoryId 分类ID，用于筛选指定分类的图书
     * @return 筛选后的图书ID列表
     *//*

    public List<String> getBookIdListByCategoryId(int page, int size, int categoryId) throws IOException
    {
        SearchResponse<BookDTO> search = client.search(s -> s
                        .index("book")
                        .query(q -> q
                                .term(t -> t
                                        .field("category_id")
                                        .value(categoryId)))
                        .storedFields("id")  //获取显式存储的字段（在mapping中设置store: true）
                        .source(source -> source
                                .filter(f -> f.excludes("*"))) //完全不返回 _source 内容,优化查询性能
                        .from((page-1)*size)
                        .size(size)
                        .sort(sort -> sort
                                .field(f -> f
                                        .field("id")
                                        .order(SortOrder.Asc)))
                , BookDTO.class);
        return search.hits().hits().stream().map(f -> f
                //指定字段
                .fields().get("id"))
                //转为字符串
                .map(f -> f.toJson().asJsonArray().getFirst().toString())
                //收集为列表
                .collect(Collectors.toList());
    }


    */
/**
     * 根据书籍名称和分类ID获取推荐书籍ID列表
     *
     * @param name 书籍名称，用于匹配搜索
     * @param categoryId 分类ID，用于精确匹配书籍分类
     * @return 包含推荐书籍ID的字符串列表
     * @throws IOException 当Elasticsearch查询出现IO异常时抛出
     *//*

    public List<Integer> getRecommendBookListById(String name, int categoryId) throws IOException
    {
        SearchResponse<BookDTO> search = client.search(s -> s
                        .index("book")
                        .query(q -> q
                                .bool(b -> b
                                        .must(m -> m
                                                .match(match -> match
                                                        .field("name")
                                                        .query(name)))
                                        .must(m -> m
                                                .term(t -> t
                                                        .field("category_id")
                                                        .value(categoryId)))))
                        .source(source -> source
                                .filter(f ->f
                                        .includes("id")))   //只返回id字段（在_source中）
                        .from(0)
                        .size(6)
                , BookDTO.class);
        return  search.hits().hits().stream()
                .filter(f -> Objects.nonNull(f.source()))
                .map(m -> m.source().getId())
                .collect(Collectors.toList());
    }


    */
/**
     * 根据搜索词获取该分类下的图书数量
     * @param searchTerm 搜索词
     * @return 该分类下的图书数量
     *//*

    public long getSearchTermBookCount(String searchTerm) throws IOException
    {
        return client.count(c -> c
                        .index("book")
                        .query(q -> q.
                                bool(b -> b
                                        .should(m -> m
                                                .match(match -> match
                                                        .field("name")
                                                        .query(searchTerm)))
                                        .should(m -> m
                                                .match(match -> match
                                                        .field("author")
                                                        .query(searchTerm)))
                                        .should(m -> m
                                                .term(t -> t
                                                        .field("isbn")
                                                        .value(searchTerm)))
                                .minimumShouldMatch("1"))))
                .count();
    }


    */
/**
     * 根据搜索词获取指定搜索词图书列表
     *
     * @param page 页码
     * @param size 每页数量
     * @return 指定页的图书列表
     *//*

   	public List<BookDTO> getSearchTermBookListBySearchTerm(int page, int size, String searchTerm) throws IOException
	{
		// 高亮查询
		SearchResponse<BookDTO> response = client.search(s -> s
						.index("book")
						.query(q -> q
								.bool(b -> b
										.should(m -> m
												.match(match -> match
														.field("name")
														.query(searchTerm)))
										.should(m -> m
												.match(match -> match
														.field("author")
														.query(searchTerm)))
										.should(m -> m
												.term(t -> t
														.field("isbn")
														.value(searchTerm)))
										.minimumShouldMatch("1")))
						.source(source -> source
								.filter(f ->f
										.includes("id", "name", "author")))
						.highlight(h -> h
								.fields("name", f -> f
										.preTags("<font color='red'>")
										.postTags("</font>"))
								.fields("author", f -> f
										.preTags("<font color='red'>")
										.postTags("</font>"))
						)
						.from((page-1)*size)
						.size(size)
				, BookDTO.class);
		// 处理结果并构建 BookDTO 列表
		return response.hits().hits().stream()
				//过滤空
				.filter(hit -> hit.source() != null)
				.map(hit -> {
					//获取源数据
					BookDTO src = hit.source();
					Map<String, List<String>> hl = hit.highlight();
					// 高亮优先逻辑内联
					String name = (hl != null && hl.containsKey("name") && !hl.get("name").isEmpty()) ? hl.get("name").getFirst() : src.getName();
					String author = (hl != null && hl.containsKey("author") && !hl.get("author").isEmpty()) ? hl.get("author").getFirst() : src.getAuthor();
					return new BookDTO(src.getId(), name, author);
				})
				.toList();
	}


    */
/**
     * 根据用户ID获取正在借阅图书数量
     * @param userId 用户ID
     * @return 借阅图书数量
     *//*

    public long getBorrowingCountById(int userId) throws IOException
    {
        return client.count(c -> c
                        .index("borrowing")
                        .query(q -> q.
                                bool(b -> b
                                        .must(m -> m
                                                .term(t -> t
                                                        .field("user_id")
                                                        .value(userId)))
                                        .should(m -> m
                                                .term(match -> match
                                                        .field("status")
                                                        .value("借阅中")))
                                        .should(s -> s
                                                .term(match -> match
                                                        .field("status")
                                                        .value("审核中")))
                                        .minimumShouldMatch("1"))))
                .count();
    }


    */
/**
     * 根据用户ID获取正在借阅图书ID列表
     * @param userId 用户ID
     * @return 正在借阅图书ID列表
     *//*

    public List<String> getBorrowingIdListById(int userId) throws IOException
    {
        SearchResponse<BookDTO> search = client.search(s -> s
                        .index("borrowing")
                        .query(q -> q
                                .bool(b -> b
                                        .must(m -> m
                                                .term(match -> match
                                                        .field("user_id")
                                                        .value(userId)))
                                        .should(m -> m
                                                .term(match -> match
                                                        .field("status")
                                                        .value("借阅中")))
                                        .should(ss -> ss
                                                .term(match -> match
                                                        .field("status")
                                                        .value("审核中")))
                                        .minimumShouldMatch("1")))
                        .storedFields("id")  //获取显式存储的字段（在mapping中设置store: true）
                        .source(source -> source
                                .filter(f -> f.excludes("*"))) //完全不返回 _source 内容,优化查询性能
                , BookDTO.class);
        return search.hits().hits().stream().map(f -> f
                        //指定字段
                        .fields().get("id"))
                //转为字符串
                .map(f -> f.toJson().asJsonArray().getFirst().toString())
                //收集为列表
                .collect(Collectors.toList());
    }


    */
/**
     * 根据用户ID获取所有借阅图书ID列表
     * @param userId 用户ID
     * @return 所有借阅图书ID列表
     *//*

    public List<String> getAllBorrowBookListById(int userId) throws IOException
    {
        SearchResponse<BookDTO> search = client.search(s -> s
                        .index("borrowing")
                        .query(q -> q
                                .term(t -> t
                                        .field("user_id")
                                        .value(userId)))
                        .storedFields("id")  //获取显式存储的字段（在mapping中设置store: true）
                        .source(source -> source
                                .filter(f -> f.excludes("*"))) //完全不返回 _source 内容,优化查询性能
                , BookDTO.class);
        return search.hits().hits().stream().map(f -> f
                        //指定字段
                        .fields().get("id"))
                //转为字符串
                .map(f -> f.toJson().asJsonArray().getFirst().toString())
                //收集为列表
                .collect(Collectors.toList());
    }


    */
/**
     * 获取所有待删除的借阅信息的ID列表
     * @return 所有待删除的借阅图书ID列表
     *//*

    public List<String> getDeleteBorrowingIdList() throws IOException
    {
        SearchResponse<BookDTO> search = client.search(s -> s
                        .index("borrowing")
                        .query(q -> q
                                .term(t -> t
                                        .field("status")
                                        .value("已归还")))
                        .storedFields("id")  //获取显式存储的字段（在mapping中设置store: true）
                        .source(source -> source
                                .filter(f -> f.excludes("*"))) //完全不返回 _source 内容,优化查询性能
                , BookDTO.class);
        return search.hits().hits().stream().map(f -> f
                        //指定字段
                        .fields().get("id"))
                //转为字符串
                .map(f -> f.toJson().asJsonArray().getFirst().toString())
                //收集为列表
                .collect(Collectors.toList());
    }


    */
/**
     * 根据用户ID获取已归还的借阅图书总数量
     * @param userId 用户ID
     * @return 借阅图书数量
     *//*

    public long getReturnCountById(int userId) throws IOException
    {
        return client.count(c -> c
                        .index("borrowing")
                        .query(q -> q.
                                bool(b -> b
                                        .must(m -> m
                                                .match(match -> match
                                                        .field("status")
                                                        .query("已归还")))
                                        .must(m -> m
                                                .term(match -> match
                                                        .field("user_id")
                                                        .value(userId))))))
                .count();
    }


    */
/**
     * 根据用户ID和搜索词获取借阅图书列表
     * @param userId 用户ID
     * @param searchTerm 搜索词
     * @return 借阅图书列表
     *//*

    public List<String> getBorrowBookListBySearch(int userId, String searchTerm) throws IOException
    {
        //根据用户输入的搜索词获取图书的id
        SearchResponse<BookDTO> search = client.search(s -> s
                        .index("book")
                        .query(q -> q
                                .bool(b -> b
                                        .should(m -> m
                                                .match(match -> match
                                                        .field("name")
                                                        .query(searchTerm)))
                                        .should(m -> m
                                                .term(match -> match
                                                        .field("isbn")
                                                        .value(searchTerm)))
                                        .minimumShouldMatch("1")))
                        .storedFields("id")  //获取显式存储的字段（在mapping中设置store: true）
                        .size(100)
                        .source(source -> source
                                .filter(f -> f.excludes("*"))) //完全不返回 _source 内容,优化查询性能
                , BookDTO.class);
        List<String> bookIdList = search.hits().hits().stream().map(f -> f
                        //指定字段
                        .fields().get("id"))
                //转为字符串
                .map(f -> f.toJson().asJsonArray().getFirst().toString())
                //收集为列表
                .toList();

        //根据用户ID和图书ID获取借阅图书列表
        SearchResponse<BookDTO> search2 = client.search(s -> s
                        .index("borrowing")
                        .query(q -> q
                                .bool(b -> b
                                        .must(m -> m
                                                // 使用 terms 查询替代 term，匹配多个 book_id
                                                .terms(t -> t
                                                        .field("book_id")
                                                        .terms(ts -> ts
                                                                // 将 List<String> 转换为 List<FieldValue>
                                                                .value(bookIdList.stream().map(FieldValue::of).collect(Collectors.toList())))))
                                        .must(m -> m
                                                .term(match -> match
                                                        .field("user_id")
                                                        .value(userId)))))
                        .storedFields("id")  //获取显式存储的字段（在mapping中设置store: true）
                        .size(100)
                        .source(source -> source
                                .filter(f -> f.excludes("*"))) //完全不返回 _source 内容,优化查询性能
                , BookDTO.class);
        return search2.hits().hits().stream().map(f -> f
                        //指定字段
                        .fields().get("id"))
                //转为字符串
                .map(f -> f.toJson().asJsonArray().getFirst().toString())
                //收集为列表
                .collect(Collectors.toList());
    }


    */
/**
     * 获取所有图书馆公告数量
     * @return 公告数量
     *//*

    public long getAllLibraryNoticeCount() throws IOException
    {
        return client.count(c -> c
                        .index("library_notice"))
                .count();
    }


    */
/**
     * 根据搜索词获取图书馆公告数量
     * @param searchTerm 搜索词
     * @return 公告数量
     *//*

    public long getSearchLibraryNoticeCount(String searchTerm) throws IOException
    {
        return client.count(c -> c
                        .index("library_notice")
                        .query(q -> q.
                                match(match -> match
                                        .field("title")
                                        .query(searchTerm))))
                .count();
    }


    */
/**
     * 根据搜索词获取指定搜索词图书公告列表
     *
     * @param page 页码
     * @param size 每页数量
     * @return 指定页的图书列表
     *//*

    public List<NoticeDTO> getSearchLibraryNoticeByPage(int page, int size, String searchTerm) throws IOException
    {
        // 高亮查询
        SearchResponse<NoticeDTO> response = client.search(s -> s
                        .index("library_notice")
                        .query(q -> q
                                        .match(match -> match
                                                .field("title")
                                                .query(searchTerm)))
                        .source(source -> source
                                .filter(f ->f
                                        .includes("id")))   //只返回id和name字段（在_source中）
                        .highlight(h -> h
                                .fields("title", f -> f
                                        .preTags("<font color='red'>")
                                        .postTags("</font>")))
                        .from((page-1)*size)
                        .size(size)
                , NoticeDTO.class);
        // 处理结果并构建 BookDTO 列表
        return response.hits().hits().stream()
                .map(m -> {
                    // 从 _source 获取 id
                    assert m.source() != null;
                    int id = m.source().getId();
                    // 从高亮结果获取 title（带标签）
                    String highlightedName = m.highlight().get("title").getFirst();
                    // 创建 BookDTO 对象（需要适配您的构造函数）
                    return new NoticeDTO(id, highlightedName);})
                .collect(Collectors.toList());
    }


    */
/**
     * 获取所有删除的图书馆公告ID列表
     * @return 删除的图书馆公告ID列表
     *//*

    public List<Integer> getDeleteLibraryNoticeIdList() throws IOException
    {
        //获取当前日期的一个月前的日期
        LocalDate oneMonthAgo = LocalDate.now().minusMonths(1);
        SearchResponse<NoticeDTO> search = client.search(s -> s
                        .index("library_notice")
                        .query(q -> q
                                .range(r -> r
                                    .field("publish_date")
                                    .lt(JsonData.of(oneMonthAgo.toString()))))
                        .source(source -> source
                                .filter(f ->f
                                        .includes("id")))   //只返回id字段（在_source中）
                        .size(500)
                , NoticeDTO.class);
        return  search.hits().hits().stream()
                .filter(f -> Objects.nonNull(f.source()))
                .map(m -> m.source().getId())
                .collect(Collectors.toList());
    }

}
*/
